<template>
  <button
    class="s-button"
    :class="c_class"
    hover-class="s-button-hover"
    :style="c_style"
    :form-type="formType"
    :open-type="openType"
    :disabled="disabled"
    @click="handleClick"
  >
    <div
      v-if="hoverEffect && !loading && !disabled"
      class="s-button-hover-mask"
      :style="'background-color:' + $sTheme('{black}')"
    ></div>
    <slot></slot>
  </button>
</template>

<script>
import addUnit from '../../utils/addUnit';
import mergeClass from '../../utils/mergeClass';
import mergeStyle from '../../utils/mergeStyle';
import buttonState from './buttonState';
import getTypeValue from '../../utils/getTypeValue';

const defaultTheme = {
  background: {
    type: String,
    default: '',
  },
  color: {
    type: String,
    default: '',
  },
  borderColor: {
    type: String,
    default: '',
  },
};

const defaultSize = {
  width: {
    type: [Number, String],
    default: '',
  },
  height: {
    type: [Number, String],
    default: '',
  },
  fontSize: {
    type: [Number, String],
    default: '',
  },
  padding: {
    type: [Number, String],
    default: '',
  },
};

export default {
  name: 'SButton',
  props: {
    customClass: {
      type: [String, Object, Array],
      default: '',
    },
    customStyle: {
      type: [String, Object],
      default: '',
    },
    type: {
      type: String,
      default: 'default',
    },
    plain: {
      type: Boolean,
      default: false,
    },
    size: {
      type: String,
      default: 'default',
    },
    block: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    square: {
      type: Boolean,
      default: false,
    },
    round: {
      type: Boolean,
      default: false,
    },
    hairline: {
      type: Boolean,
      default: false,
    },
    hoverEffect: {
      type: Boolean,
      default: true,
    },
    formType: {
      type: String,
      default: '',
    },
    openType: {
      type: String,
      default: '',
    },
  },
  data: () => ({
    buttonState,
  }),
  computed: {
    themeState() {
      const typeTheme = this.buttonState.data.type[this.type];
      const plainTheme = this.buttonState.data.plain[this.type];
      return this.getTheme(Object.assign({}, this.plain ? plainTheme || typeTheme : typeTheme));
    },
    sizeState() {
      return this.getSize(Object.assign({}, this.buttonState.data.size[this.size]));
    },
    c_class() {
      const preClass = 's-button';
      return mergeClass(
        {
          [`${preClass}-${this.type}`]: this.type,
          [`${preClass}-size-${this.size}`]: this.size,
          [`${preClass}-is-block`]: this.block,
          [`${preClass}-is-plain`]: this.plain,
          [`${preClass}-is-square`]: this.square,
          [`${preClass}-is-round`]: this.round,
          [`${preClass}-is-hairline`]: this.hairline,
          [`${'s-hairline-surround'}`]: this.hairline,
          [`${preClass}-is-loading`]: this.loading,
          [`${preClass}-is-disabled`]: this.disabled,
        },
        this.customClass,
      );
    },
    c_style() {
      const theme = this.themeState;
      const size = this.sizeState;
      const styles = {
        width: addUnit(this.block ? '100%' : size.width),
        height: addUnit(size.height),
        background: this.$sTheme(theme.background),
        color: this.$sTheme(theme.color),
        fontSize: addUnit(size.fontSize),
        padding: addUnit(size.padding),
        borderColor: this.$sTheme(theme.borderColor),
      };
      return mergeStyle(styles, this.customStyle);
    },
  },
  // 组件周期函数--监听组件挂载完毕
  mounted() {},
  // 组件周期函数--监听组件数据更新之前
  beforeUpdate() {},
  // 组件周期函数--监听组件数据更新之后
  updated() {},
  // 组件周期函数--监听组件激活(显示)
  activated() {},
  // 组件周期函数--监听组件停用(隐藏)
  deactivated() {},
  // 组件周期函数--监听组件销毁之前
  beforeDestroy() {},
  methods: {
    getTheme(themeObj) {
      const themeData = {};
      themeObj = getTypeValue(themeObj, Object, {});
      Object.keys(defaultTheme).forEach(k => {
        themeData[k] = getTypeValue(themeObj[k], defaultTheme[k].type, defaultTheme[k].default);
      });
      return themeData;
    },
    getSize(sizeObj) {
      const sizeData = {};
      sizeObj = getTypeValue(sizeObj, Object, {});
      Object.keys(defaultSize).forEach(k => {
        sizeData[k] = getTypeValue(sizeObj[k], defaultSize[k].type, defaultSize[k].default);
      });
      return sizeData;
    },
    handleClick(e) {
      if (this.loading || this.disabled) return;
      this.$emit('click', e);
    },
  },
};
</script>

<style lang="scss" scoped>
.s-button {
  margin: 0;
  padding: 0;
  position: relative;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font-size: inherit;
  line-height: 1;
  background: transparent;
  color: inherit;
  border: 0;
  border-radius: 4rpx;
  outline: none;
  appearance: none;
  touch-action: manipulation;
  user-select: none;
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
  overflow: hidden;
  box-sizing: border-box;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;

  &::after {
    border: 0;
  }
  &-default {
    border: 2rpx solid;
  }
  &-hover-mask {
    content: ' ';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 100%;
    border: inherit;
    border-radius: inherit;
    transform: translate(-50%, -50%);
    opacity: 0;
  }
  &-hover &-hover-mask {
    opacity: 0.1;
  }
  &-is-block {
    display: flex;
  }
  &-is-plain {
    border: 2rpx solid;
  }
  &-is-hairline {
    border-width: 0;
  }
  &-is-square {
    border-radius: 0;
  }
  &-is-round {
    border-radius: 999px;
  }
  &-is-loading {
    cursor: default;
  }
  &-is-disabled {
    opacity: 0.5 !important;
    cursor: not-allowed;
  }
}
</style>
